package com.ruoyi.common.utils.sign;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import java.util.Arrays;

/**
 * SM3算法工具类
 */
public class SM3Utils {

    private static final String ENCODING = "UTF-8";

    /**
     * 加密
     *
     * @param src 明文
     * @param key 密钥
     */
    public static String encrypt(String src, String key) {
        String dataSM3 = "";
        try {
            dataSM3 = ByteUtils.toHexString(getEncryptByKey(src, key));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSM3;
    }


    /**
     * SM3加密方式之： 根据自定义密钥进行加密，返回加密后长度为32位的16进制字符串
     *
     * @param src 源数据
     * @param key 密钥
     */
    public static byte[] getEncryptByKey(String src, String key) throws Exception {
        byte[] srcByte = src.getBytes(ENCODING);
        byte[] keyByte = key.getBytes(ENCODING);
        KeyParameter keyParameter = new KeyParameter(keyByte);
        SM3Digest sm3 = new SM3Digest();
        HMac hMac = new HMac(sm3);
        hMac.init(keyParameter);
        hMac.update(srcByte, 0, srcByte.length);
        byte[] result = new byte[hMac.getMacSize()];
        hMac.doFinal(result, 0);
        return result;
    }

    /**
     * 利用源数据+密钥校验与密文是否一致
     *
     * @param src       源数据
     * @param key       密钥
     * @param sm3HexStr 密文
     */
    public static boolean verify(String src, String key, String sm3HexStr) throws Exception {
        byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr);
        byte[] newHashCode = getEncryptByKey(src, key);
        return Arrays.equals(newHashCode, sm3HashCode);
    }

    public static void main(String[] args) throws Exception {
        String srcStr = "{\"dataCount\":1,\"dataContent\":[{\"uniqueId\":\"efa0c651ed4a4893aab7e5ed52d827e4\",\"siteCode\":\"450332KD01\",\"vehicleNo\":\"湘MQV182\",\"plateColor\":\"0\",\"checkNo\":\"202203192023072601684\",\"checkTime\":20220507013223,\"total\":1400,\"axles\":2,\"overRate\":0,\"overWeight\":0,\"limitWeight\":10000,\"isOverrun\":\"0\",\"speed\":37,\"laneNumber\":\"31\",\"weight1\":750,\"weight2\":650,\"weight3\":0,\"weight4\":0,\"weight5\":0,\"weight6\":0,\"weight7\":0,\"vehicleType\":\"0\",\"totalLength\":0,\"totalWidth\":0,\"totalHeight\":0,\"uploadTime\":20220507013223}]}";
        String key = "";

        // ******************************自定义密钥加密及校验*****************************************
        String hexStrByKey = SM3Utils.encrypt(srcStr, key);
        System.out.println("带密钥加密后的密文：" + hexStrByKey);
        System.out.println("明文(带密钥)与密文校验结果：" + SM3Utils.verify(srcStr, key, hexStrByKey));

        // ******************************无密钥的加密及校验******************************************
//        String hexStrNoKey = SM3Utils.encrypt(srcStr);
//        System.out.println("不带密钥加密后的密文：" + hexStrNoKey);
//        System.out.println("明文(不带密钥)与密文校验结果：" + SM3Utils.verify(srcStr, hexStrNoKey));

    }

}


